package com.atom.module.document.ui;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.atom.module.document.Document;
import com.atom.module.document.R;
import com.atom.module.document.helper.BitmapHelper;
import com.atom.module.document.helper.DocumentHelper;
import com.atom.module.document.helper.PointHelper;
import com.atom.module.document.utils.DocumentUtils;
import com.atom.module.document.utils.FileUtil;
import com.atom.module.document.view.CropView;
import com.atom.module.document.view.recycler.Adapter;
import com.atom.module.image.filter.EmptyFilter;
import com.atom.module.image.filter.Image;
import com.atom.module.logger.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.internal.observers.BlockingBaseObserver;
import io.reactivex.schedulers.Schedulers;

/**
 * All rights Reserved, Designed By www.rongdasoft.com
 *
 * @version V1.0
 * @Title: SingleHandleActivity
 * @Description:
 * @author: wuyongzheng
 * @date: 2022/3/28
 * @Copyright: 2022/3/28 www.rongdasoft.com Inc. All rights reserved.
 */
public class SingleHandleActivity extends AbstractAppCompatActivity {

    private Document.Entry singleEntry;
    private String documentName;
    private String documentPath; // 不为null 说明是有路径,
    private Bitmap oldBitmap;

    private void initParams(@Nullable Bundle savedInstanceState) {
        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return;
        }
        String singleFilePath = intent.getStringExtra(DocumentHelper.camera_result_value_param);
        if (TextUtils.isEmpty(singleFilePath)) {
            finish();
        }

        if (!new File(singleFilePath).exists()) {
            finish();
        }
        singleEntry = new Document.Entry(singleFilePath, Document.FilterWrapper.filter_empty_wrapper);
        documentPath = intent.getStringExtra(DocumentHelper.document_path_param);
        documentName = intent.getStringExtra(DocumentHelper.document_name_param);
        if (TextUtils.isEmpty(documentName)) {
            documentName = DocumentHelper.defaultDocumentName();
        }
        Logger.e("%s, %s \n", documentPath, documentName);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initParams(savedInstanceState);
        setContentView(R.layout.activity_single_handle);
        view(R.id.documentName, (PickView<EditText>) v -> {
            v.setText(documentName);
            v.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    documentName = s.toString();
                }
            });
        });
        view(R.id.autoDocumentView, (PickView<CropView>) v -> {
            v.setRangeChangeListener(point -> {
                singleEntry.setPoints(point);
                toggleAutoShear(PointHelper.isFullPoint(v.getBitmap(), point));
            });
            v.setImageBitmap(singleEntry.getRotateBitmap());
            v.setPoints(singleEntry.getPoints());
        });
        view(R.id.shutterAgainLayoutView, v -> {
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 切换为连拍
                    Document.clearDocument();
                    Document.addDocument(0, singleEntry);
                    // 跳转到拍照界面
                    Intent intent = new Intent(SingleHandleActivity.this, CameraViewActivity.class);
                    intent.putExtras(getIntent());
                    intent.putExtra(DocumentHelper.camera_model_param, false);
                    intent.putExtra(DocumentHelper.document_check_history_param, false);
                    startActivity(intent);
                    // 结束自己
                    finish();
                }
            });
        });
        view(R.id.turnLeftLayoutView, v -> {
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Observable.just(singleEntry)
                        .flatMap((Function<Document.Entry, ObservableSource<Bitmap>>) entryDocument -> new Observable<Bitmap>() {
                            @Override
                            protected void subscribeActual(Observer<? super Bitmap> observer) {
                                // 获取当前选择前的 宽高
                                Document.Param param = entryDocument.getParam();
                                // 用该宽高对当前的切割点进行旋转
                                entryDocument.setPoints(PointHelper.rotatePoint(param, -90, entryDocument.getPoints()));
                                // 保存
                                entryDocument.setRotate(-90);
                                // 获取bitmap
                                observer.onNext(entryDocument.getRotateBitmap());
                            }
                        }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new BlockingBaseObserver<Bitmap>() {
                            @Override
                            public void onNext(Bitmap bitmap) {
                                if (oldBitmap != null) {
                                    if (!oldBitmap.isRecycled()) {
                                        oldBitmap.recycle();
                                    }
                                }
                                oldBitmap = bitmap;
                                view(R.id.autoDocumentView, (PickView<CropView>) documentView -> {
                                    documentView.setImageBitmap(bitmap);
                                    documentView.setPoints(singleEntry.getPoints());
//                                    RequestOptions options = new RequestOptions()
//                                        .centerCrop()
//                                        .diskCacheStrategy(DiskCacheStrategy.NONE);
//                                    Glide.with(documentView)
//                                        .load(bitmap)
//                                        .apply(options)
//                                        .transition(DrawableTransitionOptions.withCrossFade())
//                                        .into(documentView);
                                });
                            }

                            @Override
                            public void onError(Throwable e) {

                            }
                        });
                }
            });
        });
        view(R.id.filterLayoutView, v -> {
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    view(R.id.filterRecyclerView, (PickView<RecyclerView>) view -> {
                        view.setVisibility(view.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
                        if (view.getVisibility() == View.VISIBLE) {
                            Adapter.Subject<SingleEntryFilter> date = new Adapter.Subject<SingleEntryFilter>(new Adapter.AbstractListener<SingleEntryFilter>() {

                                @Override
                                public void onItemClick(View view, Adapter.Subject<SingleEntryFilter> adapter, Adapter.ViewHolder<SingleEntryFilter> viewHolder, SingleEntryFilter singleEntryFilter) {
                                    Observable.just(SingleHandleActivity.this.singleEntry)
                                        .flatMap((Function<Document.Entry, ObservableSource<Bitmap>>) entry -> {
                                            if (singleEntryFilter.getFilterWrapper().filter instanceof EmptyFilter) {
                                                return observer -> observer.onNext(entry.getOriginalBitmap());
                                            }
                                            Bitmap rotateBitmap = entry.getRotateBitmap();
                                            Image process = singleEntryFilter.getFilterWrapper().filter.process(new Image(rotateBitmap));
                                            process.copyPixelsFromBuffer();
                                            Bitmap destImage = process.destImage;
                                            if (destImage != null && !rotateBitmap.isRecycled()) {
                                                rotateBitmap.recycle();
                                            }
                                            return observer -> observer.onNext(process.destImage);
                                        }).subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new BlockingBaseObserver<Bitmap>() {
                                            @Override
                                            public void onNext(Bitmap bitmap) {
                                                view(R.id.autoDocumentView, (PickView<ImageView>) v -> {
                                                    for (SingleEntryFilter item : adapter.getItems()) {
                                                        item.setSelect(false);
                                                    }
                                                    singleEntryFilter.setSelect(true);
                                                    adapter.notifyDataSetChanged();
                                                    v.setImageBitmap(bitmap);
                                                    singleEntry.setFilterWrapper(singleEntryFilter.getFilterWrapper());
                                                });
                                            }

                                            @Override
                                            public void onError(Throwable e) {

                                            }
                                        });
                                }
                            }) {
                                @Override
                                protected int getItemViewType(int position, SingleEntryFilter filter) {
                                    return R.layout.item_filter;
                                }

                                @Override
                                public Adapter.ViewHolder<SingleEntryFilter> onCreateViewHolder(View contentView, int viewType) {
                                    return new ViewHolder(contentView);
                                }
                            };
                            view.setLayoutManager(new LinearLayoutManager(v.getContext(), RecyclerView.HORIZONTAL, false));
                            view.setAdapter(date);
                            view.post(() -> {
                                List<SingleEntryFilter> entryFilters = new ArrayList<>();
                                for (Document.FilterWrapper filterWrapper : Document.filterWrappers) {
                                    entryFilters.add(new SingleEntryFilter(filterWrapper));
                                }
                                date.addAll(entryFilters);
                            });
                        }
                    });
                }
            });
        });
        view(R.id.autoShearLayoutView, v -> {
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    view(R.id.autoDocumentView, (PickView<CropView>) view -> {
                        // 获取当前旋转角度的bitmap
                        Bitmap rotateBitmap = view.getBitmap();
                        boolean fullPoint = PointHelper.isFullPoint(rotateBitmap, singleEntry.getPoints());
                        if (!fullPoint) {
                            view.setPoints(PointHelper.createFullPoint(rotateBitmap));
                            return;
                        }
                        DocumentUtils.analysisArray(DocumentUtils.createFrame(rotateBitmap), new BlockingBaseObserver<Point[]>() {
                            @Override
                            public void onNext(Point[] points) {
                                view(R.id.autoDocumentView, (PickView<CropView>) view -> {
                                    view.setPoints(points);
                                });
                            }

                            @Override
                            public void onError(Throwable e) {
                                Logger.e(e);
                            }
                        });
                    });
                }
            });
        });
        view(R.id.closeHandle, v -> {
            v.setOnClickListener(v12 -> onBackPressed());
        });
        view(R.id.finishHandle, v -> v.setOnClickListener(v1 -> shearDocument()));
    }

    private void shearDocument() {
        // 所有的图片都在 .document路径下
        // 将图片进行复制,从.document路径复制到documentPath指定的路径下的sourceDocument
        // 生成新的Document.Entry对象进行新处理
        if (TextUtils.isEmpty(documentPath)) {
            // 进行重新命名,命名规则使用当前的
            documentPath = DocumentHelper.getDocumentPath(this, DocumentHelper.defaultDocumentName());
        }
        // 进行重新命名,命名规则使用当前的
        String targetDocumentSourcePath = DocumentHelper.getDocumentSourcePath(documentPath);
        String defaultDocumentSourcePath = DocumentHelper.getDocumentSourcePath(this, null);
        if (FileUtil.copyFile(this.singleEntry.getSourcePath(), targetDocumentSourcePath)) {
            if (FileUtil.deleteFile(this.singleEntry.getSourcePath())) {
                String sourcePath = this.singleEntry.getSourcePath();
                String replace = sourcePath.replace(defaultDocumentSourcePath, targetDocumentSourcePath);
                Document.Entry entry = new Document.Entry(replace,
                    this.singleEntry.getFilterWrapper(),
                    this.singleEntry.getPoints(),
                    this.singleEntry.getRotate());
                saveDocumentInLocal(entry, new BlockingBaseObserver<File>() {
                    @Override
                    public void onNext(File file) {
                        Logger.e(file.getAbsolutePath());
                        ArrayList<Document.EntryWrapper> resultData = new ArrayList<>(Collections.singletonList(entry.toWrapper()));
                        Intent intent = new Intent(SingleHandleActivity.this , DocumentListActivity.class);
                        intent.putExtra(DocumentHelper.camera_result_array_param, resultData);
                        // TODO 跳转到文档详情
                        startActivity(intent);
                        finish();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                });
            }
        }
    }

    private void saveDocumentInLocal(Document.Entry entry, Observer<File> observer) {
        DocumentUtils.shearBitmapByPoints2(DocumentUtils.createFrame(entry.getRotateBitmap()), entry.getPoints())
            .map(bitmap -> {
                if (entry.getFilterWrapper() != Document.FilterWrapper.filter_empty_wrapper) {
                    Image process = entry.getFilterWrapper().filter.process(new Image(bitmap));
                    process.copyPixelsFromBuffer();
                    Bitmap destBitmap = process.destImage;
                    if (destBitmap != null && destBitmap != bitmap) {
                        if (!bitmap.isRecycled()) {
                            bitmap.recycle();
                        }
                        bitmap = destBitmap;
                    }
                }
                File saveFile = DocumentHelper.createFile(entry.createHandlePath(), true);
                try {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(saveFile));
                    return saveFile;
                } catch (Exception e) {
                    Logger.e(e);
                }
                return null;
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);
    }

    private void toggleAutoShear(boolean isFull) {
        view(R.id.autoShearTextView, (PickView<TextView>) v -> {
            v.setText(isFull ? "自动" : "全部");
        });
    }

    class ViewHolder extends Adapter.ViewHolder<SingleEntryFilter> {

        private final TextView filterName;
        private final ImageView filterShow;
        private final FrameLayout showLayout;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            filterName = itemView.findViewById(R.id.filterName);
            filterShow = itemView.findViewById(R.id.filterShow);
            showLayout = itemView.findViewById(R.id.showLayout);
        }

        @Override
        public void onBind(SingleEntryFilter filter) {
            filterName.setText(filter.getFilterWrapper().name);
            Observable.just(SingleHandleActivity.this.singleEntry)
                .flatMap((Function<Document.Entry, ObservableSource<Bitmap>>) entry -> {
                    Bitmap bitmap = BitmapHelper.centerSquareScaleBitmap(entry.getOriginalBitmap(), 250);
                    Image process = filter.getFilterWrapper().filter.process(new Image(bitmap));
                    process.copyPixelsFromBuffer();
                    return observer -> observer.onNext(process.destImage);
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new BlockingBaseObserver<Bitmap>() {
                    @Override
                    public void onNext(Bitmap bitmap) {
                        filterShow.setImageBitmap(bitmap);
                    }

                    @Override
                    public void onError(Throwable e) {
                        filterShow.setBackgroundColor(Color.RED);
                    }
                });
            if (filter.isSelect()) {
                filterName.setBackgroundResource(R.color.C0080FF_blue);
                showLayout.setBackgroundResource(R.drawable.bg_blue);
            } else {
                filterName.setBackgroundResource(R.color.C606266);
                showLayout.setBackground(null);
            }
        }
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            view(R.id.autoDocumentView, (PickView<CropView>) v -> {
                Point[] cropPoints = v.getPoints();
                if (cropPoints == null) return;
                Bitmap bitmap = singleEntry.getOriginalBitmap();
                StringBuilder builder = new StringBuilder();
                builder.append("     ").append(bitmap.getWidth()).append("--").append(bitmap.getHeight()).append("\n");
                for (Point cropPoint : cropPoints) {
                    builder.append(cropPoint).append("\n");
                }
                Logger.e(builder.toString());
            });
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onBackPressed() {
        DocumentHelper.documentDeleteShow(SingleHandleActivity.this, new BlockingBaseObserver<Boolean>() {
            @Override
            public void onNext(Boolean aBoolean) {
                if (aBoolean) {
                    // 删除照片
                    Logger.e("删除 %s ", singleEntry.getSourcePath());
                    if (DocumentHelper.deleteFile(singleEntry.getSourcePath())) {
                        singleEntry.recycleOriginalBitmap();
                    }
                    // 跳转到拍照界面
                    startActivity(new Intent(SingleHandleActivity.this, CameraViewActivity.class));
                    // 结束自己
                    finish();
                }
            }

            @Override
            public void onError(Throwable e) {

            }
        });
    }


    static class SingleEntryFilter {
        private Document.FilterWrapper filterWrapper;
        private boolean select;

        public SingleEntryFilter(Document.FilterWrapper filterWrapper) {
            this.filterWrapper = filterWrapper;
        }

        public Document.FilterWrapper getFilterWrapper() {
            return filterWrapper;
        }

        public void setFilterWrapper(Document.FilterWrapper filterWrapper) {
            this.filterWrapper = filterWrapper;
        }

        public boolean isSelect() {
            return select;
        }

        public void setSelect(boolean select) {
            this.select = select;
        }
    }

    @Override
    protected void onDestroy() {
        if (oldBitmap != null) {
            if (!oldBitmap.isRecycled()) {
                oldBitmap.recycle();
            }
        }
        if (this.singleEntry != null) {
            this.singleEntry.recycleOriginalBitmap();
        }
        super.onDestroy();
    }
}
